package jmine.selenium;

import java.net.URL;

import jmine.tec.environment.EnvironmentException;
import jmine.tec.environment.db.DBEnvironment;
import jmine.tec.services.environment.RefDBEnvironment;

import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.bio.SocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;

/**
 * Ambiente de execução de testes de selenium.
 * 
 * @author Rafael Volpato
 * @date Nov 29, 2010
 */
public class SeleniumEnvironment extends RefDBEnvironment {

    private static final int MAX_IDLE_TIME = 1000 * 60 * 60;

    private Server server;

    private final EnvironmentConfiguration config;

    /**
     * Construtor
     * 
     * @param other other
     * @param config configuração desse ambiente
     */
    public SeleniumEnvironment(DBEnvironment other, EnvironmentConfiguration config) {
        super(other);
        this.config = config;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void start() {
        super.start();

        // Start webserver
        if (this.config.getWebApplicationWARLocation() != null) {
            this.startWebServer();
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void restart() {
        if (this.config.getWebApplicationWARLocation() != null) {
            super.restart();
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void stop() {
        // Stop webserver
        if (this.config.getWebApplicationWARLocation() != null) {
            try {
                this.server.stop();
                this.server.join();
            } catch (Exception e) {
                throw new EnvironmentException(SeleniumMessages.ERROR_WEBSERVER_STOP.create(), e);
            }
        }

        super.stop();
    }

    /**
     * Inicializa o web server da aplicação
     */
    private void startWebServer() {
        if (this.server != null) {
            throw new IllegalStateException("Environment already started");
        }

        URL webApplicationURL = this.config.getWebApplicationURL();
        String warLocation = this.config.getWebApplicationWARLocation();

        this.server = new Server();
        SocketConnector connector = new SocketConnector();
        // Set some timeout options to make debugging easier.
        connector.setMaxIdleTime(MAX_IDLE_TIME);
        connector.setSoLingerTime(-1);
        connector.setPort(webApplicationURL.getPort());
        this.server.setConnectors(new Connector[]{ connector });

        WebAppContext appContext = new WebAppContext();
        appContext.setServer(this.server);
        appContext.setContextPath(webApplicationURL.getPath());
        appContext.setWar(warLocation);
        this.server.addHandler(appContext);

        try {
            this.server.start();
        } catch (Exception e) {
            throw new EnvironmentException(SeleniumMessages.ERROR_WEBSERVER_START.create(webApplicationURL, warLocation), e);
        }

        if (this.server.isFailed() || appContext.isFailed()) {
            throw new EnvironmentException(SeleniumMessages.ERROR_WEBSERVER_START.create(webApplicationURL, warLocation));
        }
    }
}
